package com.atguigu.communcation;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ClassName: ThreadOrderAccess
 * Package: com.atguigu.communcation
 * Description:
 *
 * @author: fu-wang
 * @create: 2024/10/29 18:55
 * version: 1.0
 */
public class ThreadOrderAccess {
    //声明全局锁对象
    private static Lock lock = new ReentrantLock();

    //为ABC三线程声明Condition对象负责不同线程等待，唤醒
    private static Condition conditionA = lock.newCondition();
    private static Condition conditionB = lock.newCondition();
    private static Condition conditionC = lock.newCondition();

    //声明全局flag标识，作为线程阻塞，执行条件
    private static int flag = 1;

    //AA打印5次，BB打印10次，CC打印15次
    public void printA() {
        lock.lock();

        try {
            //判断
            while (flag != 1){
                conditionA.await();
            }
            //干活
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            //通知
            flag = 2;//唤醒翻过
            conditionA.signalAll();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }
    public void printB() {
        lock.lock();
        try {
            while (flag != 2){
                conditionB.await();
            }
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            flag = 3;
            conditionB.signalAll();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }
    public void printC() {
        lock.lock();
        try {
            while (flag != 3){
                conditionC.await();
            }
            for (int i = 0; i < 15; i++) {
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            flag = 1;
            conditionC.signalAll();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }
}
class ThreadOrderAccessTest{
    public static void main(String[] args) {
        ThreadOrderAccess orderAccess = new ThreadOrderAccess();
        // 打印10轮
        for (int i = 0; i < 10; i++) {
            new Thread(orderAccess::printA,"A-thread").start();

        }
        for (int i = 0; i < 10; i++) {
            new Thread(orderAccess::printB,"B-thread").start();
        }
        for (int i = 0; i < 10; i++) {
            new Thread(orderAccess::printC,"C-thread").start();
        }

    }
}